/***
 * API: Interfaz de Integracion hacia el sistema SUB. 
 * Copyright (c) 2011 Alcaldia de Medellin.
 * Subsecretaria de Tecnologia de Informacion. 
 * Todos los Derechos Reservados.
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 * 
 */
package defecto;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;

/**
 * Clase que aplica el patron Data Access Object, para acceder al web service
 * publicado por accion social que incide en el uso del Bean
 * <code>SipodVO</code>.
 * 
 * @author Consult-Soft S.A.
 * @version 4.0 28/11/2011
 * @since 1.4
 */
public class SipodDAO {

	// ------------------------------------------------------------------------
	// Constructores
	// ------------------------------------------------------------------------

	/**
	 * Crear una nueva instancia del valueObject beneficiario.
	 * 
	 * @return BeneficiaryVO la nueva instancia de la clase con los atributos
	 *         vacios.
	 * 
	 */
	public static SipodVO createValueObject() {
		return new SipodVO();
	}

	// ------------------------------------------------------------------------
	// Metodos Publicos
	// ------------------------------------------------------------------------

	/**
	 * Crea un DAO para la clase SipodVO sin inicializar.
	 */
	public SipodDAO() {
	}

	/**
	 * Obtiene los datos de registro de una persona desplazada, registrada en el
	 * sistema SIPOD.
	 * 
	 * Consulta el web service publicado por AccionSocial, en caso de ocurrir
	 * una excepcion el sistema informara cual ha sido el problema
	 * 
	 * @param documentType
	 *            tipo de documento del desplazado
	 * @param documentNumber
	 *            numero de documento del desplazado
	 * @return El Bean con la informacion sobre el desplazado
	 * @throws SUBException
	 *             Si sucede algun evento no soportado por la llamada al web
	 *             service
	 */
	public SipodVO getRegistry(String documentType, String documentNumber) {
		// Variables locales
		Element actual = null;
		InputStream in = null;
		final int PROPIEDADESSIPOD = 13;
		final int PROPIEDADESRUPD = 7;
		final int PROPIEDADESRUPDOPCIONAL = 5;
		ConectorHttp con;
		SipodVO desplazado = SipodDAO.createValueObject();
		String parametro = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
				+ "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
				+ "<soap:Body><Registro xmlns=\"AccionSocial\">"
				+ "<Usuario>ENTIDADEXTERNA</Usuario>"
				+ "<Password>$ENTEXT*</Password>" + "<tipoDocAfiliado>"
				+ documentType + "</tipoDocAfiliado>" + "<numerodocumento>"
				+ documentNumber + "</numerodocumento>" + "</Registro>"
				+ "</soap:Body>" + "</soap:Envelope>";
		try {

			// Obtiene el inputStream a partir del resultado del request para
			// el metodoPost
			con = new ConectorHttp();
			in = con.MetodoPOST(parametro);

			// Usando las librerias de JDOM se transforma la respuesta
			// (response) en un documento usando un SAXBuilder como Factory.
			Document document;
			SAXBuilder sax = new SAXBuilder();
			document = sax.build(in);

			// // Se posiciona en la cabecera del documento.
			Element root = document.getRootElement();
			// System.out.println("NOMBRE ROOT: " + root.getName());
			if (root.getName().equals("Envelope")) {

				// Avanza hasta el body del response
				Element elementBody = root
						.getChild("Body", root.getNamespace());
				// System.out.println("NOMBRE BODY: " + elementBody.getName());

				Namespace ns = Namespace.getNamespace("AccionSocial");
				// System.out.println("NOMBRE NAMESPACE: " + ns.getURI());

				Element elementResponse = elementBody.getChild(
						"RegistroResponse", ns);
				// System.out.println("NOMBRE elementResponse: " +
				// elementResponse.getName());

				Element elementResult = elementResponse.getChild(
						"RegistroResult", ns);
				// System.out.println("NOMBRE elementResult: " +
				// elementResult.getName());
				// Guarda todos los "hijos" del response en la lista
				List resu = elementResult.getContent();
				// System.out.println("lista tam" + resu.size());
				for (Iterator ite = resu.iterator(); ite.hasNext();) {
					actual = (Element) ite.next();
					// System.out.println("NOMBRE actual: " + actual.getName());
					// System.out.println(
					// "segundo nivel tam" + actual.getContentSize());
					for (Iterator ite2 = actual.getContent().iterator(); ite2
							.hasNext();) {
						Element actual2 = (Element) ite2.next();
						// System.out.println("tercer nivel tam"
						// + actual2.getContentSize());
						for (Iterator ite3 = actual2.getContent().iterator(); ite3
								.hasNext();) {
							Element actual3 = (Element) ite3.next();
							// System.out.println("cuarto nivel tam"
							// + actual3.getContentSize());
							if (actual3.getContentSize() == PROPIEDADESSIPOD) {
								if (desplazado.getFechaVinculacion() != null) {
									String seDesplazo = actual3
											.getChildText("SE_DESPLAZO");
									String activo = actual3
											.getChildText("ACTIVO");
									String estado = actual3
											.getChildText("ESTADO");
									if ("1".equalsIgnoreCase(seDesplazo)
											&& "1".equalsIgnoreCase(activo)
											&& "Incluido"
													.equalsIgnoreCase(estado)) {
										int fechaAnterior = Integer
												.parseInt(desplazado
														.getFechaVinculacion()
														.substring(0, 4));
										int fechaNueva = Integer
												.parseInt(actual3.getChildText(
														"FECHA_VINCULACION")
														.substring(0, 4));
										if (fechaAnterior < fechaNueva) {
											desplazado
													.setTipoDesplazamiento(actual3
															.getChildText("TIPO_DEZPLAZAMIENTO"));
											desplazado
													.setDeclaracion(actual3
															.getChildText("DECLARACION"));
											desplazado.setEstado(actual3
													.getChildText("ESTADO"));
											desplazado
													.setFechaVinculacion(actual3
															.getChildText("FECHA_VINCULACION"));
											desplazado.setActivo(actual3
													.getChildText("ACTIVO"));
											desplazado
													.setSeDesplazo(actual3
															.getChildText("SE_DESPLAZO"));
											desplazado
													.setIdPersona(actual3
															.getChildText("ID_PERSONA"));
											desplazado.setRelacion(actual3
													.getChildText("RELACION"));
											desplazado
													.setDeparMunDeclaracion(actual3
															.getChildText("DEPAR_MUN_DECLARACION"));
											desplazado
													.setFechaDeclaracion(actual3
															.getChildText("FECHA_DECLARACION"));
											desplazado
													.setDeparMunExpulcion(actual3
															.getChildText("DEPAR_MUN_EXPULCION"));
											desplazado
													.setFechaDesplaz(actual3
															.getChildText("FECHADESPLAZ"));
											desplazado.setSexo(actual3
													.getChildText("SEXO"));
										}
									}
								} else {
									desplazado
											.setTipoDesplazamiento(actual3
													.getChildText("TIPO_DEZPLAZAMIENTO"));
									desplazado.setDeclaracion(actual3
											.getChildText("DECLARACION"));
									desplazado.setEstado(actual3
											.getChildText("ESTADO"));
									desplazado.setFechaVinculacion(actual3
											.getChildText("FECHA_VINCULACION"));
									desplazado.setActivo(actual3
											.getChildText("ACTIVO"));
									desplazado.setSeDesplazo(actual3
											.getChildText("SE_DESPLAZO"));
									desplazado.setIdPersona(actual3
											.getChildText("ID_PERSONA"));
									desplazado.setRelacion(actual3
											.getChildText("RELACION"));
									desplazado
											.setDeparMunDeclaracion(actual3
													.getChildText("DEPAR_MUN_DECLARACION"));
									desplazado.setFechaDeclaracion(actual3
											.getChildText("FECHA_DECLARACION"));
									desplazado
											.setDeparMunExpulcion(actual3
													.getChildText("DEPAR_MUN_EXPULCION"));
									desplazado.setFechaDesplaz(actual3
											.getChildText("FECHADESPLAZ"));
									desplazado.setSexo(actual3
											.getChildText("SEXO"));
								}
							}
							if (actual3.getContentSize() >= PROPIEDADESRUPDOPCIONAL
									&& actual3.getContentSize() <= PROPIEDADESRUPD) {
								desplazado.setId(actual3.getChildText("ID"));
								desplazado.setNombre1(actual3
										.getChildText("NOMBRE_1"));
								desplazado.setNombre2(actual3
										.getChildText("NOMBRE_2"));
								desplazado.setApellido1(actual3
										.getChildText("APELLIDO_1"));
								desplazado.setApellido2(actual3
										.getChildText("APELLIDO_2"));
								desplazado.setTipoDocumento(actual3
										.getChildText("TIPO_DOCUMENTO"));
								desplazado.setDocumento(actual3
										.getChildText("DOCUMENTO"));
							}
						}// for iterator III
					}// for iterator II
				} // fin for GLOBAL
			}
		} catch (JDOMException jdome) {
			System.err
					.println("/******** CLIENTE CONSUMO SIPOD - PARSING ERROR ** INICIO ** ");
			jdome.printStackTrace(System.err);
			System.err
					.println("** FIN ** CLIENTE CONSUMO SIPOD - PARSING ERROR ********/");
		} catch (IOException ioe) {
			System.err
					.println("/******** CLIENTE CONSUMO SIPOD - COMUNICACION ERROR ** INICIO ** ");
			ioe.printStackTrace(System.err);
			System.err
					.println("** FIN ** CLIENTE CONSUMO SIPOD - COMUNICACION ERROR ********/");
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (Exception exc) {
					System.err
							.println("/******** CLIENTE CONSUMO SIPOD ** INICIO ** ");
					exc.printStackTrace(System.err);
					System.err
							.println("** FIN ** CLIENTE CONSUMO SIPOD ********/");
				}
			}// fin if-close inputstream
		} // fin try catch finally
		return desplazado;
	} // fin metodo registro
}